#1) Loads constrained send and receive events
#2) Determines the paths for all these events
#  2a) Start condition, the node where the packet origninates changes the send event to "transmission" events
#  2b) Loop, a node either receives from a sent or forwards a received "transmission" event
#3) Also puts in one example to show how two evetns 
#   can be created when processing just for illustration purposes

# Evaluation criteria:
# a) implementability of the language construct?
#    assumption: eventset methods or slightly rewritten versions are available for the dSL
# b) optimization handling of fixed point operator
#    (the fpp can use predicates for filerting: 
#     by partitioning into distinct sets, the number of iterations
#     needed for searching matches can be reduced drastically)
# c) looks

Type :senddone do
 with :name=>:nodeid,:fieldtype=> :integer, :range => [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],:notification => :error
 with :name=>:destination, :fieldtype => :integer, :range => [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79], :notification => :warning
 with :name=>:origin, :fieldtype => :integer, :range => [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],:notification => :error
 with :name=>:seqNo, :fieldtype=> :periodic, :range => 0..255, :notification => :error
 with :name=>:time, :fieldtype => :integer, :notification => :warning
end


Type :receive do
 with :name=>:nodeid,:fieldtype=> :integer, :range => [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],:notification => :error
 with :name=>:destination, :fieldtype => :integer, :range => [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79], :notification => :warning
 with :name=>:origin, :fieldtype => :integer, :range => [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,43,44,45,46,100,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],:notification => :error
 with :name=>:seqNo, :fieldtype=> :periodic, :range => 0..255, :notification => :error
 with :name=>:time, :fieldtype => :integer, :notification => :warning
end

all = loadlog(path + '/small.log')

#Based on Application4

# a)  One example when satisfying comes in fornt of the actual processing
#     Processing is similar to before
#     transform block calls methods -> satisfies starts a predicate context (may I need a block around the following predicates)
#     Evaluate and option are methods inside a block of event-class taking one parameter and then saving this into a instance variable
#     When the satisfy returns it calls the predicate with this instance variable to evaluate
#     Maybe there's also some possibility here with some eval/method missing function to count how many variables we are looking at
#     The two calls to merge create two events - not sure this works
# b) the evaluate term can be used for pre-partitioning or filtering information for considerable speed

# c) 
#      + less noise in the language
#      + no more need for the array when returning multiple events
#      + consistent variable in the processing and predicates
#      0 
#      - evaluate and option words in front make it maybe not so intuitive to use
#      - you can only do: (term and .. and (term or term or...term)) do we need more flexible format?

routestart = all.transform do |send|
  satisfying
      evaluate send[:origin] == send[:nodeid]
      evaluate send[:type] == :senddone
  merge :type => :route,:nodeid => send[:nodeid],:seqNo => send[:seqNo],:origin => send[:origin]      
    end
    

routes = routestart.transform(:iterative) do |send, receive|
  satisfying
      evaluate send[:origin] == receive[:origin]
      evaluate send[:seqNo] == receive[:seqNo]
      option send[:nodeid] == receive[:nodeid] and receive[:type] == :route and send[:type] == :senddone
      option send[:dest] == receive[:nodeid] and send[:type] == :route and send[:type] == :receive
  merge :type => :transmission, :nodeid => receive[:nodeid], :seqNo => send[:seqNo], :origin => send[:origin]
    end
    
routestart = all.transform do |send, receive|
  satisfying
    evaluate send[:origin] == receive[:origin]
    evaluate send[:dest] = receive[:nodeid] and send[:seqNo] == receive[:seqNo]
  merge :type => :send_success, :origin => send[:origin],:nodeid   => send[:nodeid], :seqNo   => send[:seqNo]       
  merge :type => :receive_success, :origin => receive[:origin], :nodeid   => receive[:nodeid], :seqNo   => send[:seqNo]    
  end